const axios = require('axios');
const crypto = require('crypto');

const wxConfig = require('../../../config/wxapi.json');

const WxApiError = require('../../module/error/wxapierror');

/**
 * code -> openid + session_key
 * @param code
 * @returns {Promise<any>}
 */
async function code2Session (code) {
    const result = await axios.get(wxConfig.apis.code2SessionUrl, {
        params: {
            appid: wxConfig.secret.appId,
            secret: wxConfig.secret.appSecret,
            js_code: code,
            grant_type: 'authorization_code'
        }
    });
    return result.data;
}

/**
 * 解析用户加密数据
 * @param pSessionKey
 * @param encryptedData
 * @param iv
 * @returns {Promise<*>}
 */
async function decryptWxData (pSessionKey, encryptedData, iv) {
    let sessionKey = Buffer.from(pSessionKey, 'base64');
    encryptedData = Buffer.from(encryptedData, 'base64');
    iv = Buffer.from(iv, 'base64');
    let decoded;
    try {
        let decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv);
        decipher.setAutoPadding(true);
        decoded = decipher.update(encryptedData, 'binary', 'utf8');
        decoded += decipher.final('utf8');
        decoded = JSON.parse(decoded);
    } catch (err) {
        throw new WxApiError.WxDataDecryptFail();
    }
    return decoded;
}

async function decodeUserPhone (sessionKey, encryptedData, iv) {
    let wxData = await decryptWxData(sessionKey, encryptedData, iv);
    return wxData.phoneNumber;
}

module.exports = {
    code2Session,
    decodeUserPhone
};
